﻿using AutoMapper;
using Fibot.HYYY.K3Cloud.Wdt.Application.Base;
using Fibot.HYYY.K3Cloud.Wdt.Core.Entities;
using Fibot.HYYY.K3Cloud.Wdt.SQLSugar.Core;
using Fibot.Module.K3Cloud.BASE.dto;
using Fibot.Module.K3Cloud.SAL;
using Fibot.Module.K3Cloud.SAL.dto;
using Fibot.Module.K3Cloud.STK;
using Fibot.Module.K3Cloud.STK.dto;
using Fibot.Module.WangDianTong;
using Fibot.Module.WangDianTong.basic.dto;
using Fibot.Module.WangDianTong.trade.dto;
using Mapster;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SqlSugar;
using System.Data;

namespace Fibot.HYYY.K3Cloud.Wdt.Application.Services
{
    public class WdtServices
    {

        private readonly ILogger _logger;

        public WdtServices(ILogger logger)
        {
            _logger = logger;
        }

        #region 处理同步逻辑

        /// <summary>
        /// 同步店铺
        /// </summary>
        /// <returns></returns>
        public BaseHttpResultDto synShop()
        {
            BaseHttpResultDto resultDto;
            try
            {
                //new SqlConnection("server=127.0.0.1;uid=sa;pwd=123;database=AIS20231004172305").Open();
                IConfigurationRoot config = new ConfigurationBuilder()
                    .AddJsonFile("config/WdtOptions.json")
                    .AddEnvironmentVariables()
                    .Build();
                WdtOptions? wdtOptions = config.Get<WdtOptions>();
                WdtManager wdtManager = new WdtManager(wdtOptions);
                List<ShopGetOutputDto>? list = wdtManager.queryShop();
                var data = list.Adapt<List<WDT_SHOP>>();
                foreach (var item in data)
                {
                    var existsShop = DbContext.Db.Queryable<WDT_SHOP>().Where(u => u.shop_id == item.shop_id).First();
                    if (existsShop == null)
                    {
                        var sql = "insert into Z_QAAW_T_WDT_SHOP(column1) values('1'); select @@IDENTITY;delete from Z_QAAW_T_WDT_SHOP;";
                        var dt = DbContext.Db.Ado.GetDataTable(sql);
                        if (dt != null && dt.Rows.Count > 0)
                        {
                            item.FID = Convert.ToInt32(dt.Rows[0][0]);
                        }
                    }
                    else
                    {
                        item.FID = existsShop.FID;
                    }
                    item.FNUMBER = item.shop_no;
                }

                DbContext.Db.Storageable(data).ExecuteCommand();

                resultDto = new BaseHttpResultDto(data, "");
            }
            catch (Exception ex)
            {
                resultDto = new BaseHttpResultDto(data: null, _message: ex.Message);
            }
            return resultDto;
        }

        /// <summary>
        /// 同步出库单
        /// </summary>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <returns></returns>
        public BaseHttpResultDto synOutStockBill(DateTime startTime, DateTime endTime)
        {
            BaseHttpResultDto resultDto;
            try
            {
                //new SqlConnection("server=127.0.0.1;uid=sa;pwd=123;database=AIS20231004172305").Open();
                IConfigurationRoot config = new ConfigurationBuilder()
                    .AddJsonFile("config/WdtOptions.json")
                    .AddEnvironmentVariables()
                    .Build();
                WdtOptions? wdtOptions = config.Get<WdtOptions>();
                WdtManager wdtManager = new WdtManager(wdtOptions);
                List<StockoutOrderTradeGetOutputDto> list = wdtManager.QueryStockoutOrderTradeService(startTime, endTime);
                List<QAAW_T_WDT_Stockout> dataList = new List<QAAW_T_WDT_Stockout>();
                foreach (StockoutOrderTradeGetOutputDto item in list)
                {
                    try
                    {
                        DbContext.Db.BeginTran();
                        var itemList = item.details_list.Adapt<List<QAAW_T_WDT_StockoutEntry>>();
                        var itemData = item.Adapt<QAAW_T_WDT_Stockout>();
                        itemData.details_list = itemList;
                        dataList.Add(itemData);
                        DbContext.Db.CommitTran();
                    }
                    catch (Exception ex)
                    {
                        DbContext.Db.RollbackTran();
                    }
                }

                #region 插入日志表

                string headerIDSql = @"insert into z_QAAW_T_WDT_Stockout(column1) values('1')
select @@IDENTITY
delete from z_QAAW_T_WDT_Stockout";

                string entryIdSql = @"insert into z_QAAW_T_WDT_Stockoutentry(column1) values('1')
select @@IDENTITY
delete from z_QAAW_T_WDT_Stockoutentry";

                foreach (var item in dataList)
                {
                    try
                    {
                        DbContext.Db.BeginTran();
                        if (item.trade_status != "95" && item.trade_status != "110")
                        {
                            continue;
                        }
                        var existsData = DbContext.Db.Queryable<QAAW_T_WDT_Stockout>().Where(u => u.FBILLNO == item.order_no).First();
                        if (existsData == null)
                        {
                            var dt = DbContext.Db.Ado.GetDataTable(headerIDSql);
                            if (dt != null && dt.Rows.Count > 0)
                            {
                                item.FID = Convert.ToInt32(dt.Rows[0][0]);
                            }
                        }
                        else
                        {
                            continue;
                        }
                        item.FBILLNO = item.order_no;

                        DbContext.Db.Storageable(item).ExecuteCommand();

                        var itemList = item.details_list;

                        foreach (var item1 in itemList)
                        {
                            var existsDataEntry = DbContext.Db.Queryable<QAAW_T_WDT_StockoutEntry>()
                                .Where(u => u.rec_id == item1.rec_id)
                                .First();
                            if (existsDataEntry == null)
                            {
                                var dt = DbContext.Db.Ado.GetDataTable(entryIdSql);
                                if (dt != null && dt.Rows.Count > 0)
                                {
                                    item1.FEntryID = Convert.ToInt32(dt.Rows[0][0]);
                                }
                            }
                            else
                            {
                                item1.FEntryID = existsDataEntry.FEntryID;
                            }
                            item1.FID = item.FID;
                            DbContext.Db.Insertable(item1).ExecuteCommand();
                        }

                        DbContext.Db.CommitTran();
                    }
                    catch (Exception ex)
                    {
                        DbContext.Db.RollbackTran();
                    }
                }
                #endregion

                resultDto = new BaseHttpResultDto(dataList, _message: "");
            }
            catch (Exception ex)
            {
                _logger.LogError("获取旺店通销售出库单失败：" + ex.Message);
                resultDto = new BaseHttpResultDto(null, ex.Message);
            }
            return resultDto;
        }

        /// <summary>
        /// 同步单据
        /// </summary>
        /// <param name="billno"></param>
        /// <returns></returns>
        public BaseHttpResultDto synBillToCloud(string billno)
        {
            BaseHttpResultDto resultDto;
            try
            {
                string message = "";
                AssembledAppHeaderDto assembledAppHeaderDto = getAssembleApp(billno, out message);
                bool isSuccess = false;
                if (assembledAppHeaderDto != null)
                {
                    isSuccess = synAssembleApp(assembledAppHeaderDto);
                    message += isSuccess ? "" : "\r\n 组装拆卸单生成失败，如已生成，可忽略此提示";
                }

                OutStockHeaderDto outStockHeaderDto = getOutStockHeaderDto(billno, out message);
                if (outStockHeaderDto != null)
                {
                    isSuccess = synOutStock(outStockHeaderDto);
                    message += isSuccess ? "" : "\r\n 销售出库单生成失败，如已生成，可忽略此提示";
                }
                resultDto = new BaseHttpResultDto("", _message: message);
            }
            catch (Exception ex)
            {
                resultDto = new BaseHttpResultDto(null, ex.Message);
            }
            return resultDto;
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 获取组装拆卸单DTO
        /// </summary>
        /// <param name="billno"></param>
        /// <returns></returns>
        private AssembledAppHeaderDto getAssembleApp(string billno, out string message)
        {
            message = "";
            try
            {
                // 查询 组装拆卸单
                var billnoP = new SugarParameter("@BillNo", billno);
                DataSet ds = DbContext.Db.Ado.UseStoredProcedure().GetDataSetAll("PG_wdt_GetAssembledApp", billnoP);//返回dt

                DataTable dtHeader = ds.Tables[0];
                DataTable dtEntry = ds.Tables[1];
                DataTable dtSubEntry = ds.Tables[2];

                if (dtEntry.Rows.Count == 0)
                {
                    message = "未找到符合条件的旺店通出库单";
                    return null;
                }
                // 转换单据头
                AssembledAppHeaderDto header = new AssembledAppHeaderDto()
                {
                    FID = 0,
                    FBillTypeID = new BaseBasicDataDto(dtHeader.Rows[0]["FBillTypeID"].ToString() ?? ""),
                    FStockOrgId = new BaseBasicDataDto(dtHeader.Rows[0]["FStockOrgId"].ToString() ?? ""),
                    FAffairType = dtHeader.Rows[0]["FAffairType"].ToString() ?? "",
                    FDate = Convert.ToDateTime(dtHeader.Rows[0]["FDate"].ToString()),
                    FNote = dtHeader.Rows[0]["FNote"].ToString() ?? "",
                    FOwnerTypeIdHead = dtHeader.Rows[0]["FOwnerTypeIdHead"].ToString() ?? "",
                    FOwnerIdHead = new BaseBasicDataDto(dtHeader.Rows[0]["FOwnerIdHead"].ToString() ?? ""),
                    FSubProOwnTypeIdH = dtHeader.Rows[0]["FSubProOwnTypeIdH"].ToString() ?? "",
                    FSubProOwnerIdH = new BaseBasicDataDto(dtHeader.Rows[0]["FSubProOwnerIdH"].ToString() ?? ""),
                    FBillNo = dtHeader.Rows[0]["FBillNo"].ToString()
                };

                // 转换实体
                List<AssembledAppEntryDto> EntryDtos = new List<AssembledAppEntryDto>();

                // 添加组装拆卸带的成品
                foreach (DataRow item in dtEntry.Rows)
                {
                    AssembledAppEntryDto entryDto = new AssembledAppEntryDto()
                    {
                        FMaterialID = new BaseBasicDataDto(item["FMaterialID"].ToString() ?? ""),
                        FUnitID = new BaseBasicDataDto(item["FUnitID"].ToString() ?? ""),
                        FQty = Convert.ToDecimal(item["FQty"].ToString()),
                        FStockID = new BaseBasicDataDto(item["FStockID"].ToString() ?? ""),
                        FStockLocId = null,
                        FStockStatusID = new BaseBasicDataDto(item["FStockStatusID"].ToString() ?? ""),
                        FBaseUnitID = new BaseBasicDataDto(item["FBaseUnitID"].ToString() ?? ""),
                        FDescription = item["FDescription"].ToString() ?? "",
                        FOwnerTypeID = item["FOwnerTypeID"].ToString() ?? "",
                        FOwnerID = new BaseBasicDataDto(item["FOwnerID"].ToString() ?? ""),
                        FKeeperTypeID = item["FKeeperTypeID"].ToString() ?? "",
                        FKeeperID = new BaseBasicDataDto(item["FKeeperID"].ToString() ?? ""),
                        FInstockDate = Convert.ToDateTime(item["FInstockDate"]),
                        FLOT = new BaseBasicDataDto(item["FLOT"].ToString() ?? ""),
                    };
                    EntryDtos.Add(entryDto);
                }

                // 遍历生成子件
                foreach (AssembledAppEntryDto item in EntryDtos)
                {
                    List<AssembledAppSubEntryDto> subEntryDtos = new List<AssembledAppSubEntryDto>();
                    // 获取当前 组装件的子件
                    DataRow[] subRows = dtSubEntry.Select($" FSUITE_NO = '{item.FMaterialID.FNumber}'");
                    // 先进先出匹配库存
                    foreach (DataRow? subRowItem in subRows)
                    {
                        // 获取库存
                        var itemNumberP = new SugarParameter("@itemNumber", subRowItem["FMaterialIDSETY"].ToString());
                        var stockTypeP = new SugarParameter("@stockType", "zzcxzj");
                        DataSet dsInventory = DbContext.Db.Ado.UseStoredProcedure().GetDataSetAll("PG_Wdt_GetINVENTORY", itemNumberP, stockTypeP);//返回dt
                        DataTable dtInventory = dsInventory.Tables[0];
                        DataTable dtDefaultStock = dsInventory.Tables[1];
                        //需要出库的库存
                        decimal FGOODS_COUNT = Convert.ToDecimal(subRowItem["FGOODS_COUNT"]);
                        string FISBATCHMANAGE = subRowItem["FISBATCHMANAGE"].ToString();

                        string FSecUnitId = Convert.ToString(subRowItem["FAUXUNITID"]);
                        decimal FCONVERTDENOMINATOR = Convert.ToDecimal(subRowItem["FCONVERTDENOMINATOR"]);
                        decimal FCONVERTNUMERATOR = Convert.ToDecimal(subRowItem["FCONVERTNUMERATOR"]);
                        for (int i = 0; i < dtInventory.Rows.Count; i++)
                        {
                            // 当前库存行
                            var dtInventoryItem = dtInventory.Rows[i];
                            // 当前库存数量
                            decimal qty = Convert.ToDecimal(dtInventoryItem["FBASEQTY"]);
                            // 当前行数量
                            decimal currentQty = 0;
                            AssembledAppSubEntryDto subEntryDto = new AssembledAppSubEntryDto();
                            //辅助数量要和库存一直
                            decimal FSecQty = Convert.ToDecimal(dtInventoryItem["FSecQty"]);
                            // 如果说需要出库的库存大于当前行的库存
                            if (FGOODS_COUNT > qty)
                            {
                                // 当前行数量设置为库存数量
                                currentQty = qty;
                                // 需要出库的库存 是需要出库的库存 - 当前库存行数量
                                FGOODS_COUNT = FGOODS_COUNT - qty;
                            }
                            else
                            {
                                // 当前行数量 = 需要出库的库存
                                currentQty = FGOODS_COUNT;
                                // 需要出库的库存 为0
                                FGOODS_COUNT = 0;
                                if (FSecQty > 0)
                                {
                                    FSecQty = Convert.ToDecimal((FCONVERTDENOMINATOR * currentQty / FCONVERTNUMERATOR).ToString("F10"));
                                }
                            }



                            subEntryDto = new AssembledAppSubEntryDto()
                            {
                                FMaterialIDSETY = new BaseBasicDataDto(subRowItem["FMaterialIDSETY"].ToString() ?? ""),
                                FUnitIDSETY = new BaseBasicDataDto(subRowItem["FUnitIDSETY"].ToString() ?? ""),
                                FQtySETY = currentQty,
                                FStockIDSETY = new BaseBasicDataDto(dtInventoryItem["StockNumber"].ToString() ?? ""),
                                FStockLocIdSETY = null,
                                FLOTSETY = FISBATCHMANAGE == "1" ? new BaseBasicDataDto(dtInventoryItem["FLOT"].ToString() ?? "") : new BaseBasicDataDto(""),
                                FStockStatusIDSETY = new BaseBasicDataDto(dtInventoryItem["StatusNumber"].ToString() ?? ""),
                                FBaseUnitIDSETY = new BaseBasicDataDto(subRowItem["FUnitIDSETY"].ToString() ?? ""),
                                FDescriptionSETY = subRowItem["FDescription"].ToString() ?? "",
                                FOwnerTypeIDSETY = subRowItem["FOwnerTypeID"].ToString() ?? "",
                                FOwnerIDSETY = new BaseBasicDataDto(subRowItem["FOwnerID"].ToString() ?? ""),
                                FKeeperTypeIDSETY = subRowItem["FKeeperTypeID"].ToString() ?? "",
                                FKeeperIDSETY = new BaseBasicDataDto(subRowItem["FKeeperID"].ToString() ?? ""),
                                FSecQtySETY = FSecQty,
                                FSecUnitIDSETY = new BaseBasicDataDto(FSecUnitId),
                                FExtAuxUnitQtySETY = FSecQty,
                                FExtAuxUnitIdSETY = new BaseBasicDataDto(FSecUnitId),

                            };
                            subEntryDtos.Add(subEntryDto);
                            // 如果库存匹配完 ，就跳出
                            if (FGOODS_COUNT <= 0)
                            {
                                break;
                            }
                        }
                        // 如果未匹配完，就直接添加一行
                        if (FGOODS_COUNT > 0)
                        {
                            var subEntryDto = new AssembledAppSubEntryDto();
                            subEntryDto = new AssembledAppSubEntryDto()
                            {
                                FMaterialIDSETY = new BaseBasicDataDto(subRowItem["FMaterialIDSETY"].ToString() ?? ""),
                                FUnitIDSETY = new BaseBasicDataDto(subRowItem["FUnitIDSETY"].ToString() ?? ""),
                                FQtySETY = FGOODS_COUNT,
                                FStockIDSETY = new BaseBasicDataDto(dtDefaultStock.Rows[0][0].ToString()),
                                FStockLocIdSETY = null,
                                FLOTSETY = FISBATCHMANAGE == "1" ? new BaseBasicDataDto(DateTime.Now.ToString("yyyyMMdd")) : new BaseBasicDataDto(""),
                                FStockStatusIDSETY = new BaseBasicDataDto("KCZT01_SYS"),
                                FBaseUnitIDSETY = new BaseBasicDataDto(subRowItem["FBaseUnitID"].ToString() ?? ""),
                                FDescriptionSETY = subRowItem["FDescription"].ToString() ?? "",
                                FOwnerTypeIDSETY = subRowItem["FOwnerTypeID"].ToString() ?? "",
                                FOwnerIDSETY = new BaseBasicDataDto(subRowItem["FOwnerID"].ToString() ?? ""),
                                FKeeperTypeIDSETY = subRowItem["FKeeperTypeID"].ToString() ?? "",
                                FKeeperIDSETY = new BaseBasicDataDto(subRowItem["FKeeperID"].ToString() ?? ""),
                                FSecQtySETY = Convert.ToDecimal((FCONVERTDENOMINATOR * FGOODS_COUNT / FCONVERTNUMERATOR).ToString("F10")),
                                FSecUnitIDSETY = new BaseBasicDataDto(subRowItem["FAUXUNITID"].ToString()),
                                FExtAuxUnitQtySETY = Convert.ToDecimal((FCONVERTDENOMINATOR * FGOODS_COUNT / FCONVERTNUMERATOR).ToString("F10")),
                                FExtAuxUnitIdSETY = new BaseBasicDataDto(subRowItem["FAUXUNITID"].ToString()),
                            };
                            subEntryDtos.Add(subEntryDto);
                        }
                    }

                    item.FSubEntity = subEntryDtos;
                }

                header.FEntity = EntryDtos;
                return header;
            }
            catch (Exception ex)
            {
                message = ex.Message;
                return null;
            }
        }

        /// <summary>
        /// 同步生成组装拆卸单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        private bool synAssembleApp(AssembledAppHeaderDto dto)
        {
            AssembledAppService service = new AssembledAppService();
            List<string> NeedReturnFields = new List<string>() { "BillNo" };
            bool isSuccess = false;
            // 保存
            string apiResult = "";
            isSuccess = service.Save(dto, NeedReturnFields, ref apiResult);

            List<string> numbers = [dto.FBillNo];

            // 提交
            if (isSuccess)
            {
                isSuccess = service.Submit(numbers);
                _logger.LogInformation("保存成功，组装拆卸单号：" + dto.FBillNo + "\r\n" + apiResult);
            }
            else
            {
                _logger.LogError("save 组装拆卸单号 json：" + JsonConvert.SerializeObject(dto));
                _logger.LogError("保存失败，组装拆卸单号：" + dto.FBillNo + "\r\n" + apiResult);
                return false;
            }

            // 审核
            if (isSuccess)
            {
                isSuccess = service.Audit(numbers);
            }

            // 审核失败，撤销
            if (!isSuccess)
            {
                service.UnAudit(numbers);
            }
            return true;
        }

        /// <summary>
        /// 获取销售出库单DTO
        /// </summary>
        /// <param name="billNo"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        private OutStockHeaderDto? getOutStockHeaderDto(string billNo, out string message)
        {
            OutStockHeaderDto header = new OutStockHeaderDto();
            message = "";
            try
            {
                // 查询 组装拆卸单
                var billnoP = new SugarParameter("@BillNo", billNo);
                DataSet ds = DbContext.Db.Ado.UseStoredProcedure().GetDataSetAll("PG_wdt_GetOutStock", billnoP);//返回dt

                DataTable dtHeader = ds.Tables[0];
                DataTable dtSubHeader = ds.Tables[1];
                DataTable dtEntry = ds.Tables[2];
                if (dtHeader.Rows.Count == 0)
                {
                    return null;
                }
                header = new OutStockHeaderDto()
                {
                    FID = 0,
                    FBillNo = dtHeader.Rows[0]["FBillNo"].ToString(),
                    FBillTypeID = new BaseBasicDataDto(dtHeader.Rows[0]["FBillTypeID"].ToString() ?? ""),
                    FDate = Convert.ToDateTime(dtHeader.Rows[0]["FDate"].ToString()),
                    FSaleOrgId = new BaseBasicDataDto(dtHeader.Rows[0]["FSaleOrgId"].ToString() ?? ""),
                    FCustomerID = new BaseBasicDataDto(dtHeader.Rows[0]["FCustomerID"].ToString() ?? ""),
                    FReceiverID = new BaseBasicDataDto(dtHeader.Rows[0]["FReceiverID"].ToString() ?? ""),
                    FStockOrgId = new BaseBasicDataDto(dtHeader.Rows[0]["FStockOrgId"].ToString() ?? ""),
                    FLinkMan = dtHeader.Rows[0]["FLinkMan"].ToString(),
                    FReceiveAddress = dtHeader.Rows[0]["FReceiveAddress"].ToString(),
                    FSettleID = new BaseBasicDataDto(dtHeader.Rows[0]["FSettleID"].ToString() ?? ""),
                    FPayerID = new BaseBasicDataDto(dtHeader.Rows[0]["FPayerID"].ToString() ?? ""),
                    FOwnerTypeIdHead = dtHeader.Rows[0]["FOwnerTypeIdHead"].ToString() ?? "",
                    FIsTotalServiceOrCost = Convert.ToBoolean(dtHeader.Rows[0]["FIsTotalServiceOrCost"])
                };
                OutStockSubHeadEntity subHeadEntity = new OutStockSubHeadEntity()
                {
                    FSettleCurrID = new BaseBasicDataDto(dtSubHeader.Rows[0]["FSettleCurrID"].ToString() ?? ""),
                    FSettleOrgID = new BaseBasicDataDto(dtSubHeader.Rows[0]["FSettleOrgID"].ToString() ?? ""),
                    FIsIncludedTax = Convert.ToBoolean(dtSubHeader.Rows[0]["FIsIncludedTax"]),
                    FLocalCurrID = new BaseBasicDataDto(dtSubHeader.Rows[0]["FLocalCurrID"].ToString() ?? ""),
                    FExchangeRate = Convert.ToDecimal(dtSubHeader.Rows[0]["FExchangeRate"].ToString()),
                    FIsPriceExcludeTax = Convert.ToBoolean(dtSubHeader.Rows[0]["FIsPriceExcludeTax"]),

                };
                header.SubHeadEntity = subHeadEntity;
                List<OutStockEntryDto> entryDtos = new List<OutStockEntryDto>();
                foreach (DataRow item in dtEntry.Rows)
                {
                    var itemNumberP = new SugarParameter("@itemNumber", item["FMaterialID"].ToString());
                    var stockTypeP = new SugarParameter("@stockType", "xsck");
                    DataSet dsInventory = DbContext.Db.Ado.UseStoredProcedure().GetDataSetAll("PG_Wdt_GetINVENTORY", itemNumberP, stockTypeP);//返回dt
                    DataTable dtInventory = dsInventory.Tables[0];
                    DataTable dtDefaultStock = dsInventory.Tables[1];

                    string FSecUnitId = Convert.ToString(item["FAUXUNITID"]);
                    decimal FCONVERTDENOMINATOR = Convert.ToDecimal(item["FCONVERTDENOMINATOR"]);
                    decimal FCONVERTNUMERATOR = Convert.ToDecimal(item["FCONVERTNUMERATOR"]);
                    //返回dt
                    //需要出库的库存
                    decimal FGOODS_COUNT = Convert.ToDecimal(item["FRealQty"]);
                    string FISBATCHMANAGE = item["FISBATCHMANAGE"].ToString();

                    decimal FPRICE = Convert.ToDecimal(item["FPRICE"]);
                    decimal FTAXPRICE = Convert.ToDecimal(item["FTAXPRICE"]);
                    decimal FEntryTaxRate = Convert.ToDecimal(item["FEntryTaxRate"]);
                    for (int i = 0; i < dtInventory.Rows.Count; i++)
                    {
                        // 当前库存行
                        var dtInventoryItem = dtInventory.Rows[i];
                        // 当前库存数量
                        decimal qty = Convert.ToDecimal(dtInventoryItem["FBASEQTY"]);
                        // 当前行数量
                        decimal currentQty = 0;
                        OutStockEntryDto entryDto = new OutStockEntryDto();
                        //辅助数量要和库存一直
                        decimal FSecQty = Convert.ToDecimal(dtInventoryItem["FSecQty"]);
                        if (FGOODS_COUNT > qty)
                        {
                            // 当前行数量设置为库存数量
                            currentQty = qty;
                            // 需要出库的库存 是需要出库的库存 - 当前库存行数量
                            FGOODS_COUNT = FGOODS_COUNT - qty;
                            // 如果说需要出库的库存大于当前行的库存
                        }
                        else
                        {
                            // 当前行数量 = 需要出库的库存
                            currentQty = FGOODS_COUNT;
                            // 需要出库的库存 为0
                            FGOODS_COUNT = 0;
                            if (FSecQty > 0)
                            {
                                FSecQty = Convert.ToDecimal((FCONVERTDENOMINATOR * currentQty / FCONVERTNUMERATOR).ToString("F10"));
                            }
                        }
                        entryDto = new OutStockEntryDto()
                        {
                            FRowType = item["FRowType"].ToString(),
                            FMaterialID = new BaseBasicDataDto(item["FMaterialID"].ToString()),
                            FUnitID = new BaseBasicDataDto(item["FUnitID"].ToString()),
                            FRealQty = currentQty,
                            FIsFree = Convert.ToBoolean(item["FIsFree"]),
                            FOwnerTypeID = item["FOwnerTypeID"].ToString(),
                            FOwnerID = new BaseBasicDataDto(item["FOwnerID"].ToString()),
                            FLot = FISBATCHMANAGE == "1" ? new BaseBasicDataDto(dtInventoryItem["FLOT"].ToString() ?? "") : new BaseBasicDataDto(""),
                            FEntryTaxRate = Convert.ToDecimal(item["FEntryTaxRate"]),
                            FStockID = new BaseBasicDataDto(dtInventoryItem["StockNumber"].ToString() ?? ""),
                            FStockStatusID = new BaseBasicDataDto(dtInventoryItem["StatusNumber"].ToString() ?? ""),
                            FSalUnitID = new BaseBasicDataDto(item["FSalUnitID"].ToString() ?? ""),
                            FSALUNITQTY = currentQty,
                            FSALBASEQTY = currentQty,
                            FPRICEBASEQTY = currentQty,
                            FOUTCONTROL = Convert.ToBoolean(item["FOUTCONTROL"]),
                            FIsOverLegalOrg = Convert.ToBoolean(item["FIsOverLegalOrg"]),
                            FARNOTJOINQTY = currentQty,
                            FCheckDelivery = Convert.ToBoolean(item["FCheckDelivery"]),
                            FSettleBySon = Convert.ToBoolean(item["FSettleBySon"]),
                            FMaterialID_Sal = new BaseBasicDataDto(item["FMaterialID_Sal"].ToString() ?? ""),
                            FVmiBusinessStatus = Convert.ToBoolean(item["FVmiBusinessStatus"]),
                            FPRICE = FPRICE,
                            FTAXPRICE = FTAXPRICE,
                            FAMOUNT = currentQty * FPRICE,
                            FEntryTaxAmount = currentQty * FTAXPRICE - currentQty * FPRICE,
                            FAllAmount = currentQty * FTAXPRICE,
                            FEntrynote = item["FEntrynote"].ToString(),
                            FAuxUnitQty = FSecQty,
                            FAuxUnitID = new BaseBasicDataDto(FSecUnitId),
                            FExtAuxUnitQty = FSecQty,
                            FExtAuxUnitId = new BaseBasicDataDto(FSecUnitId),
                        };
                        entryDtos.Add(entryDto);
                        // 如果库存匹配完 ，就跳出
                        if (FGOODS_COUNT <= 0)
                        {
                            break;
                        }
                    }
                    // 如果未匹配完，就直接添加一行
                    if (FGOODS_COUNT > 0)
                    {
                        OutStockEntryDto entryDto = new OutStockEntryDto();
                        entryDto = new OutStockEntryDto()
                        {
                            FRowType = item["FRowType"].ToString(),
                            FMaterialID = new BaseBasicDataDto(item["FMaterialID"].ToString()),
                            FUnitID = new BaseBasicDataDto(item["FUnitID"].ToString()),
                            FRealQty = FGOODS_COUNT,
                            FIsFree = Convert.ToBoolean(item["FIsFree"]),
                            FOwnerTypeID = item["FOwnerTypeID"].ToString(),
                            FOwnerID = new BaseBasicDataDto(item["FOwnerID"].ToString()),
                            FLot = FISBATCHMANAGE == "1" ? new BaseBasicDataDto(DateTime.Now.ToString("yyyyMMdd")) : new BaseBasicDataDto(""),
                            FEntryTaxRate = Convert.ToDecimal(item["FEntryTaxRate"]),
                            FStockID = new BaseBasicDataDto(dtDefaultStock.Rows[0][0].ToString()),
                            FStockStatusID = new BaseBasicDataDto("KCZT01_SYS"),
                            FSalUnitID = new BaseBasicDataDto(item["FSalUnitID"].ToString() ?? ""),
                            FSALUNITQTY = FGOODS_COUNT,
                            FSALBASEQTY = FGOODS_COUNT,
                            FPRICEBASEQTY = FGOODS_COUNT,
                            FOUTCONTROL = Convert.ToBoolean(item["FOUTCONTROL"]),
                            FIsOverLegalOrg = Convert.ToBoolean(item["FIsOverLegalOrg"]),
                            FARNOTJOINQTY = FGOODS_COUNT,
                            FCheckDelivery = Convert.ToBoolean(item["FCheckDelivery"]),
                            FSettleBySon = Convert.ToBoolean(item["FSettleBySon"]),
                            FMaterialID_Sal = new BaseBasicDataDto(item["FMaterialID_Sal"].ToString() ?? ""),
                            FVmiBusinessStatus = Convert.ToBoolean(item["FVmiBusinessStatus"]),
                            FPRICE = FPRICE,
                            FTAXPRICE = FTAXPRICE,
                            FAMOUNT = FGOODS_COUNT * FPRICE,
                            FEntryTaxAmount = FGOODS_COUNT * FTAXPRICE - FGOODS_COUNT * FPRICE,
                            FAllAmount = FGOODS_COUNT * FTAXPRICE,
                            FEntrynote = item["FEntrynote"].ToString(),
                            FAuxUnitQty = Convert.ToDecimal((FCONVERTDENOMINATOR * FGOODS_COUNT / FCONVERTNUMERATOR).ToString("F10")),
                            FAuxUnitID = new BaseBasicDataDto(FSecUnitId),
                            FExtAuxUnitQty = Convert.ToDecimal((FCONVERTDENOMINATOR * FGOODS_COUNT / FCONVERTNUMERATOR).ToString("F10")),
                            FExtAuxUnitId = new BaseBasicDataDto(FSecUnitId),
                        };
                        entryDtos.Add(entryDto);
                    }
                }

                header.FEntity = entryDtos;
                return header;
            }
            catch (Exception ex)
            {
                message = ex.Message;
                _logger.LogError("getOutStockHeaderDto error：" + ex.Message);
                return null;
            }
        }

        /// <summary>
        /// 同步生成销售出库单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        private bool synOutStock(OutStockHeaderDto dto)
        {
            OutStockService service = new OutStockService();
            List<string> NeedReturnFields = new List<string>() { "BillNo" };
            bool isSuccess = false;
            string apiResult = "";
            // 保存
            isSuccess = service.Save(dto, NeedReturnFields, ref apiResult);

            List<string> numbers = [dto.FBillNo];

            // 提交
            if (isSuccess)
            {
                isSuccess = service.Submit(numbers);
                _logger.LogInformation("保存成功，销售出库单单号：" + dto.FBillNo + "\r\n" + apiResult);
            }
            else
            {
                _logger.LogError("save 销售出库单号 json：" + JsonConvert.SerializeObject(dto));
                _logger.LogError("保存失败，销售出库单号：" + dto.FBillNo + "\r\n" + apiResult);
                return false;
            }
            // 审核
            if (isSuccess)
            {
                isSuccess = service.Audit(numbers);
            }

            // 审核失败，撤销
            if (!isSuccess)
            {
                service.UnAudit(numbers);
            }
            return true;
        }

        #endregion

    }
}
